﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Development.Tools;
using Development.Network.Tcp;

namespace Development.Network
{
    public class UserSessionManager<T> : SafeContainer<T> where T : UserSession,new()
    {
        private static UserSessionManager<T> _instance = null;
        public static UserSessionManager<T> Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new UserSessionManager<T>();
                }
                return _instance;
            }
        }
        private Task _task = null;
        private bool _run = false;
        private DateTime _lastTime;
        public void Init()
        {
            _task = new Task(Action);
            _run = true;
            _lastTime = DateTime.Now;
            _task.Start();
        }
        void Action()
        {
            while (_run)
            {
                if (DateTime.Now.Day != _lastTime.Day)
                {
                    List<T> list = GetAll();
                    list.ForEach(t =>
                    {
                        if (!t.IsOnLine && ((DateTime.Now - t.LeaveTime).TotalDays > 1))
                        {
                            Remove(t.UserId);
                        }
                    });
                    _lastTime = DateTime.Now;
                }
                else
                {
                    ThreadUtils.Sleep(1000 * 60 * 60);
                }
            }
        }
        public void AddUser(T t)
        {
            Add(t.UserId, t);
            Log.WriteLog(ELogLevel.LOG_INFO, string.Format("user {0} enter game", t.UserId));
        }

        public void Close()
        {
            _run = false;
            GetObjectList().ForEach(u =>
                {
                    u.Close();
                });
        }

        public List<T> GetAll()
        {
            return GetObjectList();
        }

        public List<T> GetOnlineList()
        {
            List<T> list = GetObjectList();
            return list.FindAll(u => u.IsOnLine);
        }

        public void Broadcast(byte[] buffer, List<long> userids)
        {
            List<T> list = GetOnlineList();
            list.ForEach(t =>
                {
                    if(userids.Contains(t.UserId))
                    {
                        t.SendMsg(buffer);
                    }
                });
        }

        public void Broadcast(byte[] buffer)
        {
            List<T> list = GetOnlineList();
            list.ForEach(t =>
            {
               t.SendMsg(buffer);
            });
        }

        public void Broadcast(byte[] buffer, Predicate<T> condition)
        {
            List<T> list = GetOnlineList().FindAll(condition);
            list.ForEach(t =>
            {
                t.SendMsg(buffer);
            });
        }

        public T GetUser(long userId,object token)
        {
             T t = Get(userId);
             var ut = token as TcpToken;
             if (t != null)
            {
                t.SetToken(ut);
            }
            return t;
        }
    }
}
